<?PHP
#
#   FILE:  ForgottenPassword.php
#
#   Part of the Metavus digital collections platform
#   Copyright 2002-2021 Edward Almasy and Internet Scout Research Group
#   http://metavus.net
#

namespace Metavus;

use ScoutLib\ApplicationFramework;
use ScoutLib\Email;
use ScoutLib\StdLib;
use ScoutLib\User;

# request that this page not be indexed by search engines
$GLOBALS["AF"]->addMetaTag(["robots" => "noindex"]);

# ----- LOCAL FUNCTIONS ------------------------------------------------------

/**
 * Search for user and send recovery email
 * @param string $Username username or email to search
 * @return array email info to build html query if successful or error info if unsuccessful
 */
function SendRecoveryEmail(string $Username)
{
    # instantiate user factory for searching users
    $UserFactory = new UserFactory();

    if (User::IsValidLookingEMailAddress($Username)) {
            # use e-mail address field for search
            $SearchField = "EMail";
            $SearchString = User::NormalizeEMailAddress($Username);
            $ErrorCode = $Username." not found.";
    } elseif (User::IsValidUserName($Username)) {
        # else if username was entered use name field for search
        $SearchField = "UserName";
        $SearchString = User::NormalizeUserName($Username);
        $ErrorCode = $Username." not found.";
    } else {
        # set error code for no value supplied
        $ErrorCode = "Invalid name supplied.";
    }

        # if search parameters were entered
    if (isset($SearchField)) {
        # search for matching user
        $Users = $UserFactory->FindUsers(
            $SearchString,
            $SearchField,
            "CreationDate",
            0,
            1
        );
    }

    # set target user from user search
    $TargetUser = (isset($Users) && count($Users)) ? array_pop($Users) : null;

    # if user wasn't found, return error code
    if (is_null($TargetUser)) {
        return [$ErrorCode];
    }


    # get forgotten password message text
    $MailTemplate = SystemConfiguration::getInstance()->getInt("PasswordChangeTemplateId");

    # set up any needed substitutions to message text
    $ResetUrlParameters = "&UN=".urlencode($TargetUser->get("UserName"))
            ."&RC=".$TargetUser->getResetCode();
    $ResetUrl = ApplicationFramework::baseUrl()."index.php?P=ResetPassword"
            .$ResetUrlParameters;
    $ManualResetUrl = ApplicationFramework::baseUrl()
            ."index.php?P=ManuallyResetPassword";
    $OurSubstitutions = array(
            "RESETURL" => $ResetUrl,
            "RESETPARAMETERS" => $ResetUrlParameters,
            "MANUALRESETURL" => $ManualResetUrl,
            "RESETCODE" => $TargetUser->getResetCode(),
            "IPADDRESS" => @$_SERVER["REMOTE_ADDR"],
            "EMAILADDRESS" => $TargetUser->get("EMail"),
            "USERNAME" => $TargetUser->get("UserName"),
    );

    # get mailer plugin
    $Mailer = $GLOBALS["G_PluginManager"]->getPlugin("Mailer");

    # send forgotten password e-mail to user
    $MessagesSent = $Mailer->sendEmail(
        $MailTemplate,
        $TargetUser->get("EMail"),
        [],
        $OurSubstitutions
    );
    $EmailSent = ($MessagesSent > 0) ? true : false;

    # return values for use in ForgottenPasswordComplete
    return ['UU' => ($SearchField == "UserName"),
        'UN' => $SearchString,
        'ES' => $EmailSent];
}


# ----- MAIN -----------------------------------------------------------------

# form fields for setting up formui, takes in one field (username)
$FormFields = [
        "Username" => [
            "Type" => FormUI::FTYPE_TEXT,
            "Label" => "User Name or Email Address",
            "Size" => 30,
            "MaxLength" => 120,
            "Placeholder" => "",
            "Required" => true,
        ],
    ];

# instantiate formui from formfields
$H_FormUI = new FormUI($FormFields);

# get username from GET/POST if available (currently used by plugin pages)
$OutsideInput = StdLib::getFormValue("UN");

# if username was found in url, send recovery email
if (!is_null($OutsideInput)) {
    $H_UserValues = SendRecoveryEmail(urldecode($OutsideInput));
    if (count($H_UserValues) == 1) {
        FormUI::LogError($H_UserValues[0]);
    }
} else {
# act on form submission
    $ButtonPushed = StdLib::getFormValue("Submit");
    switch ($ButtonPushed) {
        case "Continue":
            $Username = $H_FormUI->GetNewValuesFromForm()["Username"];
            $H_UserValues = SendRecoveryEmail($Username);
            if (count($H_UserValues) == 1) {
                FormUI::LogError($H_UserValues[0]);
            }
            break;
        case "Cancel":
            $GLOBALS["AF"]->SetJumpToPage("Home");
            break;
    }
}
